

namespace mShare.Zeroconf {
	public errordomain Error {
	    FAILED
	}

	public interface Publisher : Object {
		public abstract bool publish(string name, uint port,
		    string type_of_service, bool password_required, 
		    string[]? txt_records) throws Error;
		public abstract void rename_at_port(uint port, string name);
		public abstract bool withdraw(uint port) throws Error;
	}
	
//#if ( USEAVAHI )
	public class AvahiPublisher : Object, Publisher {
		private string name;
		private string type_of_service;
		private uint port;
		private string[] txt_records;
		private bool password_required;
		private Avahi.EntryGroup entry_group;
	
		private bool create_service() throws Error {
			Avahi.StringList txt_records;
			if (this.txt_records != null)
				txt_records = new Avahi.StringList.from_array(this.txt_records);
			else
				txt_records = new Avahi.StringList();
			
			//txt_records.add((this.password_required) ? "Password=true" : "Password=false");
			
			try {
				var service = this.entry_group.add_service_full_strlist (
					Avahi.Interface.UNSPEC,
					Avahi.Protocol.UNSPEC, 
					0, 
					this.name, 
					this.type_of_service,
					null, 
					null, 
					(uint16)this.port, 
					txt_records);
				if (service == null)
					throw new Error.FAILED("Could not add service");
				this.entry_group.commit();
			} catch (Avahi.Error e) {
				throw new Error.FAILED("Could not add service");
			}
			return true;
		}
		
		public bool publish(string name, uint port, string type_of_service, 
		    bool password_required, string[]? txt_records) throws Error {
			this.txt_records = txt_records;
			this.password_required = password_required;
			this.name = name;
			this.port = port;
			this.type_of_service = type_of_service;
			
			try {
				var client = new Avahi.Client();
				client.start();
			
				this.entry_group = new Avahi.EntryGroup();
				this.entry_group.attach(client);
			} catch (Avahi.Error e) {
				throw new Error.FAILED(e.message);
			}
		
			this.create_service();
		
			return true;
		}
		public void rename_at_port(uint port, string name) {
		}
		public bool withdraw(uint port) {
			return true;
		}
	}
//#endif
}